package com.crypt.properties;

import com.crypt.properties.factory.CryptFactory;
import com.crypt.properties.startup.Startup;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.*;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CryptPropertiesEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private final Pattern pattern = Pattern.compile("^\\{\\s*cipher\\s*(:(.*))?\\}( [\\s\\S]+)$");

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Startup.load();
        decrypt(environment);
    }

    private void decrypt(ConfigurableEnvironment environment) {
        if (!environment.getProperty(CryptProperties.enable, Boolean.class)) return;
        Properties properties = new Properties();
        Map<String, Object> propertiesMap = Startup.copyProperties(environment);
        Set<String> keys = propertiesMap.keySet();
        CryptFactory factory = CryptFactory.instance();
        for (String key : keys) {
            Object value = propertiesMap.get(key);
            Matcher matcher = pattern.matcher(String.valueOf(value));
            if (matcher.matches()) {
                String algorithm = matcher.group(2).trim();
                String encrypted = matcher.group(3).trim();
                String decrypted = factory.decrypt(algorithm, encrypted, propertiesMap);
                properties.setProperty(key, decrypted);
            }
        }
        if (!properties.isEmpty()) {
            // override
            environment.getPropertySources().addFirst(new PropertiesPropertySource(CryptProperties.propertySourceName, properties));
        }
    }
}
